import os
import fitz  # PyMuPDF
from pathlib import Path
import logging

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

def is_scanned_pdf(pdf_path, text_threshold=500):
    """
    判断PDF文件是否为纯图片扫描文件
    
    Args:
        pdf_path (str): PDF文件路径
        text_threshold (int): 文本字符数阈值，低于此值认为是扫描文件
    
    Returns:
        bool: True表示是扫描文件，False表示不是
    """
    try:
        # 打开PDF文件
        doc = fitz.open(pdf_path)
        
        total_text_length = 0
        total_pages = len(doc)
        
        # 遍历所有页面
        for page_num in range(total_pages):
            page = doc[page_num]
            
            # 提取文本内容
            text = page.get_text()
            total_text_length += len(text.strip())
            
            # 如果文本内容足够多，说明不是纯扫描文件
            if total_text_length > text_threshold:
                doc.close()
                return False
        
        doc.close()
        
        # 如果总文本长度小于阈值，认为是扫描文件
        is_scanned = total_text_length < text_threshold
        
        logger.info(f"文件: {os.path.basename(pdf_path)}, 总文本长度: {total_text_length}, 页面数: {total_pages}, 是否扫描文件: {is_scanned}")
        
        return is_scanned
        
    except Exception as e:
        logger.error(f"处理文件 {pdf_path} 时出错: {str(e)}")
        return False

def rename_pdf_with_prefix(pdf_path, prefix="[扫描文件]"):
    """
    为PDF文件添加前缀
    
    Args:
        pdf_path (str): PDF文件路径
        prefix (str): 要添加的前缀
    
    Returns:
        str: 新的文件路径，如果重命名失败返回原路径
    """
    try:
        file_dir = os.path.dirname(pdf_path)
        file_name = os.path.basename(pdf_path)
        
        # 检查文件名是否已经有该前缀
        if file_name.startswith(prefix):
            logger.info(f"文件 {file_name} 已经有前缀，跳过")
            return pdf_path
        
        # 构造新文件名
        new_file_name = f"{prefix}{file_name}"
        new_file_path = os.path.join(file_dir, new_file_name)
        
        # 检查新文件名是否已存在
        if os.path.exists(new_file_path):
            logger.warning(f"目标文件 {new_file_path} 已存在，跳过重命名")
            return pdf_path
        
        # 重命名文件
        os.rename(pdf_path, new_file_path)
        logger.info(f"成功重命名: {file_name} -> {new_file_name}")
        return new_file_path
        
    except Exception as e:
        logger.error(f"重命名文件 {pdf_path} 时出错: {str(e)}")
        return pdf_path

def find_pdf_files(directory_path):
    """
    递归查找目录下的所有PDF文件
    
    Args:
        directory_path (str): 目录路径
    
    Returns:
        list: PDF文件路径列表
    """
    pdf_files = []
    if not os.path.exists(directory_path):
        logger.error(f"目录不存在: {directory_path}")
        return pdf_files
    
    logger.info(f"开始搜索目录: {directory_path}")
    
    for root, dirs, files in os.walk(directory_path):
        for file in files:
            if file.lower().endswith('.pdf'):
                pdf_path = os.path.join(root, file)
                pdf_files.append(pdf_path)
                logger.info(f"找到PDF文件: {pdf_path}")
    
    logger.info(f"共找到 {len(pdf_files)} 个PDF文件")
    return pdf_files

def process_pdf_directory(directory_path, prefix="[扫描文件]", text_threshold=500, dry_run=False):
    """
    处理指定目录下的所有PDF文件
    
    Args:
        directory_path (str): 目录路径
        prefix (str): 扫描文件前缀
        text_threshold (int): 文本字符数阈值
        dry_run (bool): 是否为试运行模式（不实际重命名文件）
    
    Returns:
        dict: 处理结果统计
    """
    if not os.path.exists(directory_path):
        logger.error(f"目录不存在: {directory_path}")
        return {"error": "目录不存在"}
    
    # 统计信息
    stats = {
        "total_pdfs": 0,
        "scanned_pdfs": 0,
        "renamed_pdfs": 0,
        "errors": 0,
        "skipped_pdfs": 0,
        "processed_directories": 0
    }
    
    # 首先查找所有PDF文件
    pdf_files = find_pdf_files(directory_path)
    stats["total_pdfs"] = len(pdf_files)
    
    if not pdf_files:
        logger.warning("未找到任何PDF文件")
        return stats
    
    # 处理每个PDF文件
    for i, pdf_path in enumerate(pdf_files, 1):
        logger.info(f"正在处理 ({i}/{len(pdf_files)}): {pdf_path}")
        
        try:
            # 检查是否为扫描文件
            if is_scanned_pdf(pdf_path, text_threshold):
                stats["scanned_pdfs"] += 1
                
                if dry_run:
                    logger.info(f"[试运行] 将重命名: {os.path.basename(pdf_path)} -> {prefix}{os.path.basename(pdf_path)}")
                    stats["renamed_pdfs"] += 1
                else:
                    # 重命名文件
                    new_path = rename_pdf_with_prefix(pdf_path, prefix)
                    if new_path != pdf_path:
                        stats["renamed_pdfs"] += 1
                    else:
                        stats["skipped_pdfs"] += 1
            else:
                logger.info(f"文件 {os.path.basename(pdf_path)} 不是扫描文件，跳过")
                stats["skipped_pdfs"] += 1
                
        except Exception as e:
            logger.error(f"处理文件 {pdf_path} 时出错: {str(e)}")
            stats["errors"] += 1
    
    return stats

def main():
    """
    主函数 - 提供简化的命令行接口
    """
    import argparse
    
    parser = argparse.ArgumentParser(description="检测并标记PDF扫描文件")
    parser.add_argument("directory", help="要处理的目录路径")
    parser.add_argument("--prefix", default="[扫描文件]", help="扫描文件前缀 (默认: [扫描文件])")
    parser.add_argument("--threshold", type=int, default=500, help="文本字符数阈值 (默认: 500)")
    parser.add_argument("--dry-run", action="store_true", help="试运行模式，不实际重命名文件")
    
    args = parser.parse_args()
    
    print(f"🔍 PDF扫描文件检测工具")
    print(f"📁 处理目录: {args.directory}")
    print(f"🏷️ 扫描文件前缀: {args.prefix}")
    print(f"📊 文本阈值: {args.threshold}")
    print(f"🧪 试运行模式: {'是' if args.dry_run else '否'}")
    print("-" * 60)
    
    # 处理PDF文件
    stats = process_pdf_directory(
        args.directory, 
        args.prefix, 
        args.threshold, 
        args.dry_run
    )
    
    # 打印统计结果
    print("\n" + "=" * 60)
    print("✅ 处理完成！统计结果:")
    print(f"📄 总PDF文件数: {stats['total_pdfs']}")
    print(f"📷 扫描文件数: {stats['scanned_pdfs']}")
    print(f"✏️ 重命名文件数: {stats['renamed_pdfs']}")
    print(f"⏭️ 跳过文件数: {stats['skipped_pdfs']}")
    print(f"❌ 错误文件数: {stats['errors']}")
    print("=" * 60)

if __name__ == "__main__":
    # 简化的交互式使用
    if len(os.sys.argv) == 1:
        print("🔍 PDF扫描文件检测工具")
        print("=" * 40)
        
        # 获取目录路径
        directory = input("📁 请输入要处理的目录路径 (直接回车使用当前目录): ").strip()
        if not directory:
            directory = "."  # 默认当前目录
        
        # 确认是否试运行
        dry_run_input = input("🧪 是否试运行模式？(y/N，直接回车开始实际处理): ").strip().lower()
        dry_run = dry_run_input in ['y', 'yes', '是']
        
        print(f"\n🔍 PDF扫描文件检测工具")
        print(f"📁 处理目录: {directory}")
        print(f"🏷️ 扫描文件前缀: [扫描文件]")
        print(f"📊 文本阈值: 500")
        print(f"🧪 试运行模式: {'是' if dry_run else '否'}")
        print("-" * 60)
        
        # 处理PDF文件
        stats = process_pdf_directory(directory, "[扫描文件]", 500, dry_run)
        
        # 打印统计结果
        print("\n" + "=" * 60)
        print("✅ 处理完成！统计结果:")
        print(f"📄 总PDF文件数: {stats['total_pdfs']}")
        print(f"📷 扫描文件数: {stats['scanned_pdfs']}")
        print(f"✏️ 重命名文件数: {stats['renamed_pdfs']}")
        print(f"⏭️ 跳过文件数: {stats['skipped_pdfs']}")
        print(f"❌ 错误文件数: {stats['errors']}")
        print("=" * 60)
    else:
        main()
